package com.wang.todoList.service.impl;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wang.todoList.VO.PasswordVo;
import com.wang.todoList.dao.AdminMapper;
import com.wang.todoList.entity.Admin;
import com.wang.todoList.service.AdminService;
import com.wang.todoList.util.CommonUtil;
import com.wang.todoList.util.JwtUtil;
import com.wang.todoList.util.PasswordUtil;
import com.wang.todoList.util.ResponseUtil;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author zifan
 * @since 2021-07-10
 */
@Service
public class AdminServiceImpl extends ServiceImpl<AdminMapper, Admin> implements AdminService {
    /**
     * 用户注册
     * @param admin 用户实体
     * @return 返回结果
     */
    @Override
    public Map<String, Object> register(Admin admin) {
        //校验手机号是否重复
        QueryWrapper<Admin> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(Admin::getTelNumber, admin.getTelNumber());
        if (this.count(queryWrapper) != 0) {
            return ResponseUtil.getFailureRes("手机号重复！");
        }
        //检验用户名是否重复
        QueryWrapper<Admin> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.lambda().eq(Admin::getUsername,admin.getUsername());
        if (this.count(queryWrapper1)!=0){
            return ResponseUtil.getFailureRes("用户名重复！");
        }
        //对密码进行加密
        admin.setPassword(PasswordUtil.encryption(admin.getPassword()));
        //入库
        this.save(admin);
        return ResponseUtil.getSuccessRes();
    }

    /**
     * 用户登录
     * @param admin
     */
    @Override
    public Map<String, Object> login(Admin admin) {
        //对密码进行加密，看加密后是否和数据库保持一致
        String encryption = PasswordUtil.encryption(admin.getPassword());
        QueryWrapper<Admin> wrapper = new QueryWrapper<>();
        wrapper.lambda()
                .and(w -> w.eq(Admin::getUsername, admin.getUsername())
                        .eq(Admin::getPassword, encryption));
        Admin one = this.getOne(wrapper);
        if (ObjectUtil.isNull(one)){
            return ResponseUtil.getFailureRes("用户名或者密码错误！");
        }
        //验证成功，生成token并返回给前端。
        Integer id = one.getId();
        Map<String, Object> resMap = ResponseUtil.getSuccessRes();
        resMap.put("token", JwtUtil.createToken(id));
        return resMap;
    }

    /**
     * 获取用户信息
     */
    @Override
    public Map<String,Object> getAdminInfo(HttpServletRequest request) {
        Integer userId = CommonUtil.getUserId(request);
        Admin admin = this.getById(userId);
        admin.setPassword("用户密码已加密！");
        return ResponseUtil.getSuccessRes(admin);
    }

    /**
     * 修改用户信息
     */
    @Override
    public Map<String, Object> modifyAdminInfo(HttpServletRequest request,Admin admin) {
        Integer userId = CommonUtil.getUserId(request);
        if (!ObjectUtil.equal(userId,admin.getId())){
            return ResponseUtil.getFailureRes("不能修改他人信息！");
        }
        //根据id查询密码，因为密码信息本接口不修改
        QueryWrapper<Admin> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(Admin::getId,userId).select(Admin::getPassword);
        admin.setPassword(this.getOne(queryWrapper).getPassword());
        //todo 添加校验
        if (this.updateById(admin)) {
            return ResponseUtil.getSuccessRes();
        }
        return ResponseUtil.getFailureRes();
    }

    /**
     * 校验密码是否正确
     */
    @Override
    public Map<String, Object> checkPassword(HttpServletRequest request, PasswordVo passwordVo) {
        Integer userId = CommonUtil.getUserId(request);
        String encryption = PasswordUtil.encryption(passwordVo.getOldPassword());
        QueryWrapper<Admin> wrapper = new QueryWrapper<>();
        wrapper.lambda().and(w->{
            w.eq(Admin::getPassword,encryption).eq(Admin::getId,userId);
        });
        if (this.count(wrapper) == 0) {
            return ResponseUtil.getFailureRes();
        }
        return ResponseUtil.getSuccessRes();
    }

    /**
     * 生成验证码值
     */
    @Override
    public void captcha(HttpServletRequest request, HttpServletResponse response) {
        //通过响应流直接传一个图片过去，此时需要对响应头做处理。
        // 定义response输出类型为image/jpeg类型
        response.setDateHeader("Expires", 0);
        // Set standard HTTP/1.1 no-cache headers.
        response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
        // Set IE extended HTTP/1.1 no-cache headers (use addHeader).
        response.addHeader("Cache-Control", "post-check=0, pre-check=0");
        // Set standard HTTP/1.0 no-cache header.
        response.setHeader("Pragma", "no-cache");
        // return a jpeg
        response.setContentType("image/jpeg");
        //-------------------生成验证码 begin --------------------------
        LineCaptcha captcha = CaptchaUtil.createLineCaptcha(200, 100);
        request.getSession().setAttribute("captcha",captcha.getCode());
        ServletOutputStream outputStream = null;
        try {
            outputStream = response.getOutputStream();
            captcha.write(outputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (ObjectUtil.isNotNull(outputStream)){
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        //-------------------生成验证码 end ----------------------------
    }

    /**
     * 修改密码
     */
    @Override
    public Map<String, Object> updatePassword(HttpServletRequest request, PasswordVo passwordVo) {
        //校验验证码
        String captcha = (String) request.getSession().getAttribute("captcha");
        if (ObjectUtil.notEqual(captcha,passwordVo.getCode())){
            return ResponseUtil.getFailureRes("验证码不正确！");
        }

        //当前登录用户id
        Integer userId = CommonUtil.getUserId(request);
        UpdateWrapper<Admin> wrapper = new UpdateWrapper<>();
        wrapper.lambda().eq(Admin::getId, userId)
                .set(Admin::getPassword, PasswordUtil.encryption(passwordVo.getNewPassword()));
        if (this.update(wrapper)) {
            return ResponseUtil.getSuccessRes();
        }
        return ResponseUtil.getFailureRes("修改失败！请联系管理员。");
    }
}
